package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.heima.article.service.ArticleContentService;
import com.heima.article.service.ArticleFreemarkerService;
import com.heima.article.service.ArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.search.vos.SearchArticleVo;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.common.ApUserThreadLocalUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class ArticleFreemarkerServiceImpl implements ArticleFreemarkerService {

    @Autowired
    ArticleService articleService;

    @Autowired
    ArticleContentService articleContentService;


    @Autowired
    FileStorageService fileStorageService;

    @Autowired
    private Configuration configuration;

    @Autowired
    KafkaTemplate<String,String> kafkaTemplate;

    @Override
    @Async
    public void buildArticleToMinIO(ApArticle apArticle, String content) throws TemplateException, IOException {
        //1.获取文章内容
        ApArticle article = articleService.getById(apArticle.getId());

        ApArticleContent apArticleContent = articleContentService.getOne(new QueryWrapper<ApArticleContent>().lambda().
                eq(ApArticleContent::getArticleId, article.getId()));
        //2.文章内容通过freemarker生成html文件
        if(apArticleContent!=null&& StringUtils.isNotBlank(apArticleContent.getContent())){
            Template template = configuration.getTemplate("article.ftl");
            Map<String, Object> params = new HashMap<>();
            params.put("content", JSON.parseArray(apArticleContent.getContent()));
            //生成文件
            StringWriter out = new StringWriter();
            template.process(params,out);
            InputStream inputStream=new ByteArrayInputStream(out.toString().getBytes());
            //3.把html文件上传到minio中
            String s = fileStorageService.uploadHtmlFile("", article.getId().toString()+".html", inputStream);
            //4.修改ap_article表，保存static_url字段
            article.setStaticUrl(s);
            createIndexForEs(article,apArticleContent);
            articleService.updateById(article);
        }

    }


    /**
     * 异步在索引库中添加文章信息
     * @param article
     * @param apArticleContent
     */
    @Async
    public void createIndexForEs(ApArticle article, ApArticleContent apArticleContent) {
        SearchArticleVo searchArticleVo = new SearchArticleVo();
        BeanUtils.copyProperties(article,searchArticleVo);
        searchArticleVo.setContent(apArticleContent.getContent());
        List<String> suggestion = createSuggestion(searchArticleVo);
        searchArticleVo.setSuggestion(suggestion);
        kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC,JSON.toJSONString(searchArticleVo));
    }

    //添加自动补全
    private List<String> createSuggestion(SearchArticleVo item) {
        List<String> list = new ArrayList<>();
        String content = item.getContent();

        List<Map<String,String>> list1 = JSON.parseObject(content, List.class);
        list1.forEach(map->{
            if("text".equals(map.get("type"))){
                String value = map.get("value");
                for (String s : value.split(",")) {
                    list.add(s);
                }
            }
        });
        list.add(item.getTitle());
        return list;
    }


}
